package com.bcxj.apidriver.service;

import com.bcxj.apidriver.client.ServiceDriverUserClient;
import com.bcxj.apidriver.client.ServiceVerificationcodeClient;
import com.bcxj.internalcommon.constant.CommonStatusEnum;
import com.bcxj.internalcommon.constant.DriverCarConstants;
import com.bcxj.internalcommon.constant.IdentityConstant;
import com.bcxj.internalcommon.constant.TokenConstant;
import com.bcxj.internalcommon.dto.ResponseResult;
import com.bcxj.internalcommon.dto.VerificationCodeDTO;
import com.bcxj.internalcommon.response.DriverUserExistResponse;
import com.bcxj.internalcommon.response.NumberCodeResponse;
import com.bcxj.internalcommon.response.TokenResponse;
import com.bcxj.internalcommon.util.JwtUtils;
import com.bcxj.internalcommon.util.RedisPrefixUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * ClassName: VerificationCodeService
 * Package: com.bcxj.apidriver.service
 * Description:
 *
 * @Author BCXJ
 * @Create 2024/10/20 17:57
 * @Version 1.0
 * @Since 1.0
 */
@Service
@Slf4j
public class VerificationCodeService {

    @Autowired
    private ServiceDriverUserClient serviceDriverUserClient;
    @Autowired
    private ServiceVerificationcodeClient serviceVerificationcodeClient;
    @Autowired
    private StringRedisTemplate redisTemplate;


    /**
     * 司机登录获取验证码
     * @param driverPhone
     * @return
     */
    public ResponseResult checkAndSendVerificationCode(String driverPhone) {
        // 司机是否存在
        ResponseResult<DriverUserExistResponse> driverUserResp = serviceDriverUserClient.getUser(driverPhone);
        DriverUserExistResponse driverUserExistResponse = driverUserResp.getData();
        if(driverUserExistResponse.getIfExist() == DriverCarConstants.DRIVER_NOT_EXISTS){
            return ResponseResult.fail(CommonStatusEnum.DRIVER_NOT_EXIST);
        }
        log.info("司机存在{}", driverPhone);

        // 获取验证码
        ResponseResult<NumberCodeResponse> numberCodeResponseResponseResult = serviceVerificationcodeClient.numberCode(6);
        log.info("获取到的验证码为{}", numberCodeResponseResponseResult.getData().getNumberCode());

        // 第三方发送验证码(略)

        // 存入redis
        String key = RedisPrefixUtils.generatorKeyByPhone(driverPhone, IdentityConstant.DRIVER_IDENTITY);
        redisTemplate.opsForValue().set(key, numberCodeResponseResponseResult.getData().getNumberCode(), 2, TimeUnit.MINUTES);

        return ResponseResult.success();
    }

    /**
     * 校验验证码
     * @param verificationCodeDTO 验证码实体类
     * @return
     */
    public ResponseResult<TokenResponse> checkCode(VerificationCodeDTO verificationCodeDTO) {
        System.out.println("效验的手机号: " + verificationCodeDTO.getDriverPhone());
        System.out.println("输入的验证码：" + verificationCodeDTO.getVerificationCode());

        // 1 获取Redis的数据
        String key = RedisPrefixUtils.generatorKeyByPhone(verificationCodeDTO.getDriverPhone(), IdentityConstant.DRIVER_IDENTITY);
        String code = redisTemplate.opsForValue().get(key);
        System.out.println("验证码Code：" + code);

        // 2 与Redis的进行比对
        // 2.1 不存在数据
        // 验证码过期
        if(StringUtils.isBlank(code)) {
            return ResponseResult.fail(CommonStatusEnum.VERIFICATION_CODE_OVERDUE.getCode(), CommonStatusEnum.VERIFICATION_CODE_OVERDUE.getMessage());
        }
        // 2.2 存在数据
        // 2.2.1 不匹配
        // 输入验证码不正确
        if(!code.equals(verificationCodeDTO.getVerificationCode().trim())){
            return ResponseResult.fail(CommonStatusEnum.VERIFICATION_CODE_ERROR.getCode(), CommonStatusEnum.VERIFICATION_CODE_ERROR.getMessage());
        }

        // 司机与乘客的区别是，司机的登录不需要注册，因为司机的信息是后台录入的

        // 3 生成并返回accesstoken
        String accessToken = JwtUtils.generatorToken(verificationCodeDTO.getDriverPhone(), IdentityConstant.DRIVER_IDENTITY, TokenConstant.ACCESS_TOKEN);
        String refreshToken = JwtUtils.generatorToken(verificationCodeDTO.getDriverPhone(), IdentityConstant.DRIVER_IDENTITY, TokenConstant.REFRESH_TOKEN);
        // 3. token存入Redis中的数据
        String accessTokenKey = RedisPrefixUtils.generatorTokenKey(verificationCodeDTO.getDriverPhone(), IdentityConstant.DRIVER_IDENTITY, TokenConstant.ACCESS_TOKEN);
        String refreshTokenKey = RedisPrefixUtils.generatorTokenKey(verificationCodeDTO.getDriverPhone(), IdentityConstant.DRIVER_IDENTITY, TokenConstant.REFRESH_TOKEN);
        redisTemplate.opsForValue().set(accessTokenKey, accessToken, 30, TimeUnit.MINUTES);
        redisTemplate.opsForValue().set(refreshTokenKey, refreshToken, 1, TimeUnit.DAYS);

        // 3.2 返回token
        TokenResponse tokenResponse = new TokenResponse();
        tokenResponse.setAccessToken(accessToken);
        tokenResponse.setRefreshToken(refreshToken);
        return ResponseResult.success(tokenResponse);
    }
}
